package InterviewOfCollections;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/*
 * Author: JacksonCoder
 * FileName: BasicOfMap
 * Version: 1.0.0
 */
public class BasicOfMap {
    public static void main(String[] args) {
//        HashMapExample();
//        LinkedHashMapExample();
//        TreeMapExample();
//        HashTableExample();
        concurrentHashMapExample();
    }

    public static void concurrentHashMapExample(){
//        synchronized
        // 创建一个 ConcurrentHashMap
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

        // 添加键值对
        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);

        System.out.println("Map after removal: " + map);

        // 读取数据
        System.out.println("Value of A: " + map.get("A"));

        // 检查键或值是否存在
        System.out.println("Contains key 'B': " + map.containsKey("B"));
        System.out.println("Contains value 3: " + map.containsValue(3));

        // 遍历
        map.forEach((key, value) -> System.out.println(key + " -> " + value));

        // 使用 compute 方法
        map.compute("A", (key, value) -> value == null ? 1 : value + 1);
        System.out.println("Updated value of A: " + map.get("A"));

        // 使用 putIfAbsent
        map.putIfAbsent("D", 4);
        System.out.println("Value of D: " + map.get("D"));

        // 删除键值对
        map.remove("B");
        System.out.println("Map after removal: " + map);
    }

    public static void HashTableExample(){
        // 创建一个 Hashtable
        Hashtable<String, Integer> hashtable = new Hashtable<>();

        // 添加元素
        hashtable.put("One", 1);
        hashtable.put("Two", 2);
        hashtable.put("Three", 3);

        // 获取值
        System.out.println("Value for 'One': " + hashtable.get("One"));

        // 检查是否包含键或值
        System.out.println("Contains key 'Two': " + hashtable.containsKey("Two"));
        System.out.println("Contains value 3: " + hashtable.containsValue(3));

        // 遍历
        hashtable.forEach((key, value) -> System.out.println(key + " -> " + value));
    }

    public static void TreeMapExample(){
        // 创建一个 TreeMap
        TreeMap<Integer, String> treeMap = new TreeMap<>();

        // 添加元素（自动排序）
        treeMap.put(3, "Three");
        treeMap.put(1, "One");
        treeMap.put(2, "Two");

        // 遍历
        System.out.println("Sorted Order:");
        treeMap.forEach((key, value) -> System.out.println(key + " -> " + value));

        // 获取子映射
        System.out.println("SubMap (1 to 2): " + treeMap.subMap(1, 3));

        // 获取大于等于指定键的键值对
        System.out.println(treeMap.ceilingEntry(1));

        treeMap.replace(1, "New One");
        treeMap.forEach((key, value) -> System.out.println(key + " -> " + value));
    }

    public static void LinkedHashMapExample(){
        // 创建一个 LinkedHashMap
        LinkedHashMap<Integer, String> linkedMap = new LinkedHashMap<>();

        // 添加元素
        linkedMap.put(1, "One");
        linkedMap.put(2, "Two");
        linkedMap.put(3, "Three");

        // 遍历
        System.out.println("Insertion Order:");
        linkedMap.forEach((key, value) -> System.out.println(key + " -> " + value));

        // 按访问顺序访问
        String s = linkedMap.get(2);// 访问 key=2
        System.out.println(s);
        boolean empty = linkedMap.isEmpty();
        System.out.println(empty);
        System.out.println("Access Order:");
        linkedMap.forEach((key, value) -> System.out.println(key + " -> " + value));

        System.out.println(linkedMap.hashCode());
        System.out.println(linkedMap.equals(linkedMap));

    }

    public static void HashMapExample(){
        HashMap<String,Integer> hashMap = new HashMap<>();

        hashMap.put("Jackson", 1);
        hashMap.put("WuSir", 2);
        hashMap.put("Alen", 3);
        hashMap.put("Alice", 4);
        hashMap.put("Egon", 5);
        hashMap.put("Yuan", 6);

        System.out.println(hashMap);

        // get
        System.out.println("Alen: " + hashMap.get("Alen"));
        // not exist print null
        System.out.println("Grape: " + hashMap.get("Grape"));

        // modify value
        hashMap.put("Alen", 4);
        System.out.println("Update after Alen: " + hashMap.get("Alen"));

        // check contain key
        System.out.println("Contains key 'Alen': \t" + hashMap.containsKey("Alen"));
        System.out.println("Contains key 'apple': \t" + hashMap.containsKey("apple"));

        // check contain value
        System.out.println("Contains value '1': \t" + hashMap.containsValue(1));
        System.out.println("Contains value '98': \t" + hashMap.containsValue(98));

        // loop hashMap
        for(Map.Entry<String, Integer> entry : hashMap.entrySet()){
            System.out.println(entry.getKey() + "\t" + entry.getValue());
        }

        // 删除一个键值对
        hashMap.remove("Yuan");

        // 输出删除后的 HashMap
        System.out.println(hashMap);

        // 返回键值对的数量
        System.out.println(hashMap.size());

        // 返回 true 或 false
        System.out.println(hashMap.isEmpty());

        // 返回键值对集合
        System.out.println(hashMap.entrySet());

        // 返回所有键的集合
        System.out.println(hashMap.keySet());

        // 返回所有值的集合
        System.out.println(hashMap.values());

        // 清空 HashMap
        hashMap.clear();
        System.out.println(hashMap);
    }


}
